﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 画图
{
    public class LineCoordinates: LineBaseParam
    {
        private int _startIndex = 0;
        /// <summary>
        /// 起点索引
        /// </summary>
        public int StartIndex { get => this._startIndex; }
        private int _endIndex = 1;
        /// <summary>
        /// 终点索引
        /// </summary>
        public int EndIndex { get => this._endIndex; }
        private int _pointNum = 0;
        public int PointNum { get=>this._pointNum; set=>this._pointNum=value; }
        public Point[] Points = new Point[2];


        private int _lineWidth = 5;
        public int LineWidth { get => this._lineWidth; }


        private int _offsetToB = 15;
        public int OffsetToB { get => this._offsetToB; }


        private bool _selected = false;
        public bool Selected {
            get => this._selected;
            set => this._selected = value;
        }

        private void InitPoints(int h,int w) {
            this.StartPoint = new Point(Points[StartIndex].X, Points[StartIndex].Y);
            this.EndPoint = new Point(Points[EndIndex].X, Points[EndIndex].Y);
            this.XZoom = 1;
            this.YZoom = 1;

            this.CanvasCurrH = this.CanvasStartH = h;
            this.CanvasCurrW = this.CanvasStartW = w;
        }

        public void CalcCanvasZoom(int h, int w) {

            //更新画布当前值
            this.CanvasCurrH = h;
            this.CanvasCurrW = w;

            //计算长与宽的缩放倍数
            this.YZoom = (double)this.CanvasCurrH / this.CanvasStartH;
            this.XZoom = (double)this.CanvasCurrW / this.CanvasStartW;

            //对坐标点的x轴进行缩放
            Points[StartIndex].X = (int)(this.StartPoint.X * this.XZoom);
            Points[EndIndex].X = (int)(this.EndPoint.X * this.XZoom);

            //对坐标点的y轴进行缩放
            Points[StartIndex].Y = (int)(this.StartPoint.Y * this.YZoom);
            Points[EndIndex].Y = (int)(this.EndPoint.Y * this.YZoom);

            //计算K值
            this.KValue = CalcK(Points[StartIndex], Points[EndIndex]);
            //计算b值
            this.BValue = CalcB(Points[StartIndex]);
        }


        /// <summary>
        /// 求直线斜率
        /// </summary>
        public void InitKandB(int h,int w) {

            this.InitPoints(h,w);
            this.KValue = CalcK(Points[StartIndex], Points[EndIndex]);//((double)this.Points[this.EndIndex].Y - this.Points[this.StartIndex].Y) / ((double)this.Points[this.EndIndex].X - this.Points[this.StartIndex].X);
            this.BValue = CalcB(this.Points[this.StartIndex]);
            //this._endB = CalcB(this.Points[this.EndIndex]);

            Debug.Print("线段 起始坐标：(" + this.Points[this.StartIndex].X.ToString() + "," + this.Points[this.StartIndex].Y.ToString() + ")  结束坐标：(" + this.Points[this.EndIndex].X.ToString() 
                + "," + this.Points[this.EndIndex].Y.ToString() + ") K=" + this.KValue.ToString() + ",B=" + this.BValue.ToString() );
        }

        /// <summary>
        /// 计算斜率
        /// </summary>
        /// <param name="sPoint">起始点坐标</param>
        /// <param name="ePoint">结束点坐标</param>
        /// <returns></returns>
        private double CalcK(Point sPoint, Point ePoint) {
            return ((double)ePoint.Y - sPoint.Y) / ((double)ePoint.X - sPoint.X);
        }

        /// <summary>
        /// 求y=kx+b公式中的  b => 有 b = y - kx
        /// 通过偏移求点是否在直线上，是否可行？
        /// </summary>
        private double CalcB(Point SelectedPoint) {
            return (SelectedPoint.Y - this.KValue * SelectedPoint.X);
        }

        /// <summary>
        /// 计算选择的点是否在线上
        /// 计算条件：
        /// 特殊情况处理：
        ///         1、平行于y轴，在
        /// 一般判断条件：
        ///         在y轴上平移
        /// </summary>
        /// <param name="SelectedPoint"></param>
        /// <returns></returns>
        public bool CalcSelectedPoint(Point SelectedPoint) {

            //1、处理x1=x2的情况，即线段平行于y轴
            if (Math.Abs(Points[StartIndex].X-Points[EndIndex].X) < OffsetToB || Double.IsInfinity(KValue) ) {//这一行是否还需要添加对斜率的判断？

                //小于10个像素点，即认为平行
                //先判断y值
                if ((Points[StartIndex].Y <= SelectedPoint.Y && SelectedPoint.Y <= Points[EndIndex].Y)
                 || (Points[EndIndex].Y <= SelectedPoint.Y && SelectedPoint.Y <= Points[StartIndex].Y)) {
                    //这里只以起始点进行判断，可能会出现误判的情况
                    //判断坐标点的x值是否在有效范围内
                    if ((Points[StartIndex].X - OffsetToB) <= SelectedPoint.X && SelectedPoint.X <= (Points[StartIndex].X + OffsetToB)) {
                        this._selected = true;
                        return this._selected;
                    } else
                        this._selected = false;
                }
            }

            //计算普通情况
            double yMin = KValue * SelectedPoint.X + (BValue - _offsetToB);//下偏
            double yMax = KValue * SelectedPoint.X + (BValue + _offsetToB);//上偏
            if ((yMin <= SelectedPoint.Y && SelectedPoint.Y <= yMax) || (yMax <= SelectedPoint.Y && SelectedPoint.Y <= yMin))//判断是否在上下偏移的范围内命中
                this._selected = true;//是，即将选择标志设置为true
            else
                this._selected = false;

            return this._selected;
        }
    }
}
